/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.knowledge.plans;

import com.environment.Aim;
import com.environment.Percept;
import com.environment.Tile;
import com.knowledge.facts.Condition;
import com.knowledge.facts.EnemyAntFact;
import com.knowledge.facts.Fact;
import com.knowledge.facts.FactRepository;
import com.knowledge.facts.FoodFact;
import com.knowledge.facts.FriendlyAntFact;
import com.knowledge.facts.FriendlyHillFact;
import com.knowledge.facts.paths.GotoFoodPathFact;
import com.knowledge.facts.paths.GotoHivePathFact;
import com.utils.InvalidException;
import com.utils.WeightedDistance;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 *
 * @author keithballantyne
 */
@SuppressWarnings("unchecked")
public class DefendHivePlan extends Plan {


    public DefendHivePlan() {
        preconditions.add(new Condition(Condition.Op.ASSERT,FoodFact.class));
        
        postconditions.add(new Condition(Condition.Op.CLEAR,FoodFact.class));
        postconditions.add(new Condition(Condition.Op.ASSERT,FriendlyAntFact.class));
    }

    int defenders = (int) ((float) 3.0*Math.log10(Percept.getInstance().getMyAnts().size()));

    @Override
    public void calculateUtility() {
        Set<Fact> hives = FactRepository.getInstance().getInstances(FriendlyHillFact.class);
        List<FriendlyAntFact> ants = new ArrayList(FactRepository.getInstance().getFriendlyAnts());
        List<EnemyAntFact> foes = new ArrayList(FactRepository.getInstance().getInstances(EnemyAntFact.class));
        
        if (hives.isEmpty()) return;
        for (Fact hive: hives) {
            if (foes.isEmpty()) break;
            Collections.sort(foes,new WeightedDistance(hive.getLocation()));
            
            if (Percept.getInstance().getDistance2(foes.iterator().next().getLocation(), hive.getLocation()) > 2*Percept.getInstance().getViewRadius2()) break;
            
            Collections.sort(ants,new WeightedDistance(hive.getLocation()));
            int index=0;
            for (FriendlyAntFact myAnt: ants) {
                try {
                    GotoHivePathFact path = (GotoHivePathFact) myAnt.getReference(GotoHivePathFact.class);

                    // if closest ant has a path to the food, update utility of existing food path.
                    if (path != null && hive.getLocation().equals(path.getLocation())) {
                        path.setUtility(2*Percept.getInstance().getViewRadius2() - index*path.getRemainingSteps()*path.getRemainingSteps());
                    // otherwise create a path and associate it with the ant.
                    } else {
                        List<Aim> directions = Percept.getInstance().getDirections(myAnt.getLocation(), hive.getLocation());

                        path = new GotoHivePathFact(myAnt.getLocation(),hive.getLocation(),directions);
                        path.setUtility(2*Percept.getInstance().getViewRadius2() - index*path.getRemainingSteps()*path.getRemainingSteps());
                        FactRepository.getInstance().addInstance(path);
                        myAnt.setReference(path);
                    }

    //                movement.add(new Order(path.getSource(),path.getNextAim()));
                } catch (InvalidException ex) {
    //                Logger.getLogger(GotoFoodPlan.class.getName()).log(Level.SEVERE, null, ex);
                }
            index++;
            if (index > defenders) break;
            }
        }
    }

    @Override
    public Set<Condition> getMissingPreconditions() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
}
